package com.coai.twin.tracking

import com.coai.common.event.BusinessNode
import kotlinx.coroutines.flow.Flow
import org.springframework.kafka.core.KafkaTemplate
import org.springframework.messaging.simp.SimpMessagingTemplate
import org.springframework.stereotype.Service
import java.time.Instant
import java.util.UUID

/**
 * 业务节点追踪服务
 */
@Service
class BusinessNodeTracker(
    private val eventStore: EventStore,
    private val timeSeriesWriter: TimeSeriesWriter,
    private val metricsEngine: MetricsEngine,
    private val kafkaTemplate: KafkaTemplate<String, Any>,
    private val messagingTemplate: SimpMessagingTemplate
) {
    
    /**
     * 追踪业务事件
     */
    suspend fun trackEvent(event: BusinessEvent) {
        // 1. 持久化到事件存储
        val storedEvent = eventStore.append(event)
        
        // 2. 写入时序数据库
        timeSeriesWriter.write(
            measurement = event.nodeType.name,
            tags = mapOf(
                "node" to event.nodeType.name,
                "entity_id" to event.entityId,
                "user_id" to event.userId
            ),
            fields = event.metrics,
            timestamp = storedEvent.timestamp
        )
        
        // 3. 计算实时指标
        val calculatedMetrics = metricsEngine.calculate(event)
        
        // 4. 发布到Kafka
        kafkaTemplate.send("business-events", event.entityId, event)
        
        // 5. WebSocket实时推送
        messagingTemplate.convertAndSend(
            "/topic/events/${event.nodeType}",
            EventNotification(
                event = event,
                metrics = calculatedMetrics,
                timestamp = Instant.now()
            )
        )
        
        // 6. 检查业务规则
        checkBusinessRules(event, calculatedMetrics)
    }
    
    /**
     * 获取实体历史
     */
    suspend fun getEntityHistory(
        entityId: String,
        entityType: EntityType
    ): EntityHistory {
        val events = eventStore.readStream(entityId)
        
        val timeline = events.map { event ->
            TimelineEntry(
                timestamp = event.timestamp,
                eventType = event.type,
                data = event.data,
                actor = event.metadata.userId
            )
        }
        
        return EntityHistory(
            entityId = entityId,
            entityType = entityType,
            timeline = timeline,
            currentState = replayEvents(events)
        )
    }
    
    /**
     * 获取节点实时指标
     */
    suspend fun getNodeMetrics(
        nodeType: BusinessNode,
        timeRange: TimeRange
    ): Map<String, MetricValue> {
        return metricsEngine.getMetricsForNode(nodeType, timeRange)
    }
    
    private fun checkBusinessRules(event: BusinessEvent, metrics: Map<String, MetricValue>) {
        // 实现业务规则检查
        try {
            // 规列1: 库存预警
            if (event.nodeType == BusinessNode.WAREHOUSE) {
                metrics["inventory_level"]?.let { inventoryLevel ->
                    if (inventoryLevel.value < 100) {
                        logger.warn("Low inventory alert: ${inventoryLevel.value}")
                        // TODO: 发送预警通知
                    }
                }
            }
            
            // 规列2: 订单延迟预警
            if (event.nodeType == BusinessNode.ORDER_PROCESSING) {
                metrics["processing_time"]?.let { processingTime ->
                    if (processingTime.value > 3600) { // 超过1小时
                        logger.warn("Order processing delay: ${processingTime.value}s")
                    }
                }
            }
            
            // 规列3: 质量预警
            if (event.nodeType == BusinessNode.QUALITY_CHECK) {
                metrics["defect_rate"]?.let { defectRate ->
                    if (defectRate.value > 0.05) { // 次品率超过5%
                        logger.warn("High defect rate: ${defectRate.value * 100}%")
                    }
                }
            }
            
            // 规列4: 成本预警
            metrics["cost"]?.let { cost ->
                metrics["budget"]?.let { budget ->
                    if (cost.value > budget.value * 0.9) {
                        logger.warn("Cost approaching budget: ${cost.value}/${budget.value}")
                    }
                }
            }
        } catch (e: Exception) {
            logger.error("Failed to check business rules", e)
        }
    }
    
    private fun replayEvents(events: List<StoredEvent>): Map<String, Any> {
        // TODO: 事件溯源重建状态
        return emptyMap()
    }
}

/**
 * 业务事件
 */
data class BusinessEvent(
    val id: String = UUID.randomUUID().toString(),
    val nodeType: BusinessNode,
    val type: String,
    val entityId: String,
    val entityType: EntityType,
    val data: Map<String, Any>,
    val metrics: Map<String, Double>,
    val userId: String,
    val tenantId: String,
    val correlationId: String,
    val timestamp: Instant = Instant.now()
)

enum class EntityType {
    ORDER, PRODUCT, INVENTORY, SHIPMENT, PRODUCTION_ORDER, PURCHASE_ORDER
}

data class EventNotification(
    val event: BusinessEvent,
    val metrics: Map<String, MetricValue>,
    val timestamp: Instant
)

data class EntityHistory(
    val entityId: String,
    val entityType: EntityType,
    val timeline: List<TimelineEntry>,
    val currentState: Map<String, Any>
)

data class TimelineEntry(
    val timestamp: Instant,
    val eventType: String,
    val data: Map<String, Any>,
    val actor: String
)

data class MetricValue(
    val value: Double,
    val timestamp: Instant,
    val unit: String = "",
    val trend: Trend? = null
)

enum class Trend {
    INCREASING, DECREASING, STABLE
}

data class TimeRange(
    val start: Instant,
    val end: Instant
) {
    companion object {
        val LAST_HOUR = TimeRange(
            Instant.now().minusSeconds(3600),
            Instant.now()
        )
        val LAST_24_HOURS = TimeRange(
            Instant.now().minusSeconds(86400),
            Instant.now()
        )
    }
}

/**
 * 事件存储接口
 */
interface EventStore {
    suspend fun append(event: BusinessEvent): StoredEvent
    suspend fun readStream(streamId: String): List<StoredEvent>
}

data class StoredEvent(
    val id: String,
    val streamId: String,
    val type: String,
    val data: Map<String, Any>,
    val metadata: EventMetadata,
    val timestamp: Instant,
    val version: Long
)

data class EventMetadata(
    val userId: String,
    val correlationId: String,
    val causationId: String?,
    val tenantId: String
)

/**
 * 时序数据写入器
 */
interface TimeSeriesWriter {
    suspend fun write(
        measurement: String,
        tags: Map<String, String>,
        fields: Map<String, Double>,
        timestamp: Instant
    )
}

/**
 * 指标计算引擎
 */
interface MetricsEngine {
    suspend fun calculate(event: BusinessEvent): Map<String, MetricValue>
    suspend fun getMetricsForNode(nodeType: BusinessNode, timeRange: TimeRange): Map<String, MetricValue>
}
